今天這篇文章主要會介紹 Cypress 的基本結構以及常見的語法,那我們馬上開始吧!
Cypress 的測試基本結構是由 Test Group, Test Item, Command 和 Assertion 所組成的
describe('Todo List', () => { // Test Group
it('Does do much!', () => { // Test Item
expect(true).to.equal(true) // Assertion
})
it('create 2 items', () => { // Test Item
cy.visit('https://todomvc.com/examples/vue') // Command
cy.get('.new-todo') // Command
.type('todo A{enter}') // Command
.type('todo B{enter}') // Command
cy.get('.todo-list li') // Command
.should('have.length', 2) // Assertion
})
})
有看過我之前介紹的 Vue 3 單元測試 (Unit Testing) - Vue Test Utils + Jest 基本範例 & 核心語法 的朋友肯定會覺得 describe, it & expect 很熟悉,不過要注意的是,Cypress 並不是採用 Jest 而是 Mocha (describe & it) 和 Chai (expect)。
和在寫單元測試一樣,要攥寫每一筆 E2E 測試時都要以 it 為測試的最小單位,如果想要將一至多組相關聯的測試組合在一起則可以使用 describe。
command 是用來告訴 Cypress 要執行什麼動作的命令,我們可以透過一行一行的 command chain來讓它模擬使用者在網頁操作的行為。
it('create 2 items', () => {
cy.visit('https://todomvc.com/examples/vue') // command
cy.get('.new-todo') // command
.type('todo A{enter}') // command
.type('todo B{enter}') // command
})
這些 command 通常也很容易翻譯成人類可以讀懂的樣子
-> 瀏覽 https://todomvc.com/examples/vue
-> 找到 class 為 .new-todo 的元素
-> 輸入完 todd A 後按下 enter
-> 輸入完 todo B 後按下 enter
Assertions describe the desired state of your elements, your objects, and your application.
Assertions (斷言) 是用來描述了元素、物件和應用程序的期望狀態,來確保 command (命令) 的結果符合我們所預期的。
因為 Cypress 整合了很多套件,所以我們有很多種斷言的函示可以選擇,像是
又或者是 Cypress 內建的 should,should 可以傳入來自 Chai, Chai-jQuery 或 Sinon-Chai 的 Chainer,例如:
// Length
cy.get('li.selected').should('have.length', 3)
// Class
cy.get('form').find('input').should('not.have.class', 'disabled')
// Value
cy.get('textarea').should('have.value', 'foo bar baz')
// Visibility
cy.get('li').should('be.visible')
cy.get('li.hidden').should('not.be.visible')
儘管 Cypress 提供了許多斷言,但有時候最好的測試可能可以沒有斷言!
it('create 2 items', () => {
cy.visit('https://todomvc.com/examples/vue')
cy.get('.new-todo')
.type('todo A{enter}')
.type('todo B{enter}')
})
什麼意思呢? 在這個例子中我們沒有寫明確的斷言,但這個測試仍然可能會以多種方式失敗,例如
事實上這是因為許多命令都有一個預設內建的斷言,或者更準確的說,有一些命令可能會因為執行失敗導致測試錯誤而無需添加明顯的 (explicit) 斷言。
與其他測試框架不同的是 Cypress 中有一部分的命令 (command) 會自動重試斷言直到 timeout 為止。(預設下,timeout 的長度為 4 秒)
cy.get('button').click().should('have.class', 'active')
$('button').on('click', (e) => {
setTimeout(() => {
$(e.target).addClass('active')
}, 2000)
})
在上面的例子中,儘管我們在點擊 button 兩秒後才加上 active
的 class ,這條測試依然會通過。
大部分會 retry 的命令都是和 DOM 有關,例如:cy.get()、.find()、.contains() 等,你可以在 API 文件中的 ”Assertions“ 的部分來檢查這個命令是否會 retry。例如 .first()。
今天的分享就到這邊,如果大家對我分享的內容有興趣歡迎點擊追蹤 & 訂閱系列文章,如果對內容有任何疑問,或是文章內容有錯誤,都非常歡迎留言討論或指教的!